/**
 * @brief Start sending pair request after power-on.
 *      If get pair request, add the remote address
 *      and the local address to get the access address. 
 * 
 * @copyright Copyright (c) 2022 zerosensei
 * 
 */
#include "rf_pair.h"
#include "device_config.h"
#include "sys/byteorder.h"

#ifdef CONFIG_RF_PAIR

#ifdef CONFIG_RF_PAIR_DEBUG
#define RF_PAIR_DBG  PRINT
#else
#define RF_PAIR_DBG
#endif


uint8_t rf_pair_task = 0;
bool is_pair_timeout = true;

struct rf_pair pair_buf[2];
struct rf_pair *current_pair_dev;

uint32_t rf_local_addr;
uint32_t rf_access_addr;

void rf_pair_end(void);


int rf_pair_deal(uint8_t *data, uint8_t len)
{
    if(is_pair_timeout)
        return -RF_EACCES;

    if(!len || !data)
        return -RF_EINVAL;

    struct rf_pair *pair_rcv = (struct rf_pair *)data;

    //choose current device
    if(pair_rcv->dev == RF_DEV_KBD){
        current_pair_dev = &pair_buf[0];
    } else if(pair_rcv->dev == RF_DEV_MOUSE){
        current_pair_dev = &pair_buf[1];
    } else {
       return 0; /*error*/
    }

    tmos_memcpy(current_pair_dev, data, len);
    rf_access_addr = current_pair_dev->addr;

    tmos_set_event(rf_pair_task, RF_PAIR_END_EVT);

    return 0;
}

int rf_pair_start(void)
{
    RF_PAIR_DBG("start pair\n");
    uint8_t mac_temp[6];
    GetMACAddress( mac_temp );
    rf_local_addr = sys_get_le32(mac_temp);
    tmos_memset(pair_buf, 0, sizeof(pair_buf));

    struct rf_pair pair_temp = {
            .dev = RF_ALL_DEV,
    };

    pair_temp.addr = rf_local_addr;

    RF_PAIR_DBG("local addr %#lx\n", rf_local_addr);

    rf_set_addr(DEFAULT_MAC);
    int ret = rf_port_load_data_irq(RF_TYPE_REQ_PAIR, (uint8_t *)&pair_temp, sizeof(pair_temp));
    if(ret < 0)
        RF_PAIR_DBG("pair: %d\n", ret);

    return 0;
}

void rf_pair_end(void)
{
    RF_PAIR_DBG("pair end\n");

    if(current_pair_dev->dev == RF_DEV_KBD){
        RF_PAIR_DBG("paired kbd\n");
        device_rf.rf_kbd.Pair_flag = 1,
        device_rf.rf_kbd.Mac_addr = current_pair_dev->addr;
        RF_PAIR_DBG("rf access addr:%#lx\n", current_pair_dev->addr);
        tmos_memset(current_pair_dev, 0, sizeof(pair_buf[0]));
    }else{
       return ;
    }

    if(current_pair_dev->dev == RF_DEV_MOUSE){
        RF_PAIR_DBG("paired mouse\n");
        device_rf.rf_mouse.Pair_flag = 1,
        device_rf.rf_mouse.Mac_addr = current_pair_dev->addr;
        RF_PAIR_DBG("rf access addr:%#lx\n", current_pair_dev->addr);
        tmos_memset(current_pair_dev, 0, sizeof(pair_buf[0]));
    }

    tmos_start_task(rf_pair_task, RF_PAIR_TIMEOUT_EVT, MS1_TO_SYSTEM_TIME(0));
    SaveDeviceInfo("device_rf");
}

uint16_t RF_Pair_ProcessEvent(uint8_t task_id, uint16_t events)
{
    if (events & SYS_EVENT_MSG) {
        uint8 *pMsg;

        if ((pMsg = tmos_msg_receive(task_id)) != NULL) {

            // Release the TMOS message
            tmos_msg_deallocate(pMsg);
        }
        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
    }

    if(events & RF_PAIR_TIMEOUT_EVT){
        is_pair_timeout = true;
        tmos_set_event(rf_pair_task, RF_GET_KEY_EVT);
        return (events ^ RF_PAIR_TIMEOUT_EVT);
    }

    if(events & RF_PAIR_END_EVT){
        rf_pair_end();
        return (events ^ RF_PAIR_END_EVT);
    }

    if(events & RF_GET_KEY_EVT){
        if(rf_port_load_data_irq(RF_TYPE_REQ_KEY, NULL, 0) == -RF_EACCES){
            tmos_start_task(rf_pair_task, RF_GET_KEY_EVT, MS1_TO_SYSTEM_TIME(4));
        }
        return (events ^ RF_GET_KEY_EVT);
    }
    return 0;
}

void rf_pair_task_init(void)
{
    is_pair_timeout = false;
    rf_pair_task = TMOS_ProcessEventRegister(RF_Pair_ProcessEvent);
    tmos_start_task(rf_pair_task, RF_PAIR_TIMEOUT_EVT, MS1_TO_SYSTEM_TIME(CONFIG_RF_DG_PAIR_TO));
}

#endif /* CONFGI_RF_PAIR */
